package com.zzh.partnersys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzh.partnersys.common.exception.BusinessException;
import com.zzh.partnersys.common.exception.ResultCodeEnum;
import com.zzh.partnersys.entity.CollabDocumentDO;
import com.zzh.partnersys.entity.CollabDocumentVersion;
import com.zzh.partnersys.entity.request.CollabDocumentCreateRequest;
import com.zzh.partnersys.entity.request.CollabDocumentQueryRequest;
import com.zzh.partnersys.entity.request.CollabDocumentUpdateRequest;
import com.zzh.partnersys.entity.vo.CollabDocumentVO;
import com.zzh.partnersys.entity.vo.CollabDocumentVersionVO;
import com.zzh.partnersys.mapper.CollabDocumentMapper;
import com.zzh.partnersys.mapper.CollabDocumentVersionMapper;
import com.zzh.partnersys.service.CollabDocumentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 在线文档表（支撑日报/周报/自定义协作文档） 服务实现�? * </p>
 *
 * @author zzh
 * @since 2025-11-01
 */
@Service
@Slf4j
public class CollabDocumentServiceImpl extends ServiceImpl<CollabDocumentMapper, CollabDocumentDO> implements CollabDocumentService {

    @Resource
    private CollabDocumentMapper collabDocumentMapper;

    @Resource
    private CollabDocumentVersionMapper collabDocumentVersionMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CollabDocumentDO createDocument(CollabDocumentCreateRequest request, Long userId) {
        // 参数校验
        if (StringUtils.isBlank(request.getDocTitle())) {
            throw new RuntimeException("文档标题不能为空");
        }
        if (request.getDocType() == null || (request.getDocType() < 1 || request.getDocType() > 4)) {
            throw new RuntimeException("文档类型不合法");
        }
        if (request.getTeamId() == null) {
            request.setTeamId(0L);
        }
        if (request.getPermission() == null) {
            request.setPermission(2);
        }

        // 创建文档
        CollabDocumentDO document = new CollabDocumentDO();
        BeanUtils.copyProperties(request, document);
        document.setCreatorUid(userId);
        document.setLastEditorUid(userId);
        document.setVersion(1); // 初始版本�?
        document.setEditStatus(0); // 初始未锁�?        document.setIsDelete(0);

        boolean saved = this.save(document);
        if (!saved) {
            throw new RuntimeException("文档创建失败");
        }

        // 插入初始版本记录
        CollabDocumentVersion version = new CollabDocumentVersion();
        version.setDocId(document.getId());
        version.setVersion(1);
        version.setDocContent(request.getDocContent());
        version.setEditorUid(userId);
        version.setEditNote("文档创建");
        version.setIsDelete(0);

        boolean versionSaved = collabDocumentVersionMapper.insert(version) > 0;
        if (!versionSaved) {
            throw new RuntimeException("版本记录创建失败");
        }

        return document;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CollabDocumentDO updateDocument(CollabDocumentUpdateRequest request, Long userId) {
        // 获取文档
        CollabDocumentDO document = this.getById(request.getId());
        if (document == null || document.getIsDelete() == 1) {
            throw new RuntimeException(ResultCodeEnum.DOCUMENT_NOT_FOUND.getMessage());
        }

        // 检查权�?
        this.checkPermission(document, userId, 2);

        // 检查锁定状�?
        if (document.getEditStatus() == 1 && !document.getLastEditorUid().equals(userId)) {
            throw new BusinessException(ResultCodeEnum.DOCUMENT_EDIT_LOCKED);
        }

        // 查询当前版本�?
        Integer currentVersion = document.getVersion();
        Integer newVersion = currentVersion + 1;

        // 更新文档
        if (StringUtils.isNotBlank(request.getDocTitle())) {
            document.setDocTitle(request.getDocTitle());
        }
        if (request.getDocContent() != null) {
            document.setDocContent(request.getDocContent());
        }
        if (request.getPermission() != null) {
            document.setPermission(request.getPermission());
        }
        document.setVersion(newVersion);
        document.setLastEditorUid(userId);

        boolean updated = this.updateById(document);
        if (!updated) {
            throw new RuntimeException("文档更新失败");
        }

        // 插入新版本记�?
        CollabDocumentVersion version = new CollabDocumentVersion();
        version.setDocId(document.getId());
        version.setVersion(newVersion);
        version.setDocContent(request.getDocContent() != null ? request.getDocContent() : document.getDocContent());
        version.setEditorUid(userId);
        version.setEditNote(request.getEditNote() != null ? request.getEditNote() : "文档更新");
        version.setIsDelete(0);

        boolean versionSaved = collabDocumentVersionMapper.insert(version) > 0;
        if (!versionSaved) {
            throw new RuntimeException("版本记录创建失败");
        }

        return document;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteDocument(Long id, Long userId) {
        // 获取文档
        CollabDocumentDO document = this.getById(id);
        if (document == null || document.getIsDelete() == 1) {
            throw new RuntimeException(ResultCodeEnum.DOCUMENT_NOT_FOUND.getMessage());
        }

        // 检查权限（只有创建者可以删除）
        if (!document.getCreatorUid().equals(userId)) {
            throw new RuntimeException(ResultCodeEnum.DOCUMENT_PERMISSION_DENIED.getMessage());
        }

        // 逻辑删除文档
        document.setIsDelete(1);
        return this.updateById(document);
    }

    @Override
    public CollabDocumentVO getDocumentById(Long id, Long userId) {
        // 获取文档
        CollabDocumentDO document = this.getById(id);
        if (document == null || document.getIsDelete() == 1) {
            throw new RuntimeException(ResultCodeEnum.DOCUMENT_NOT_FOUND.getMessage());
        }

        // 检查权�?        this.checkPermission(document, userId, 1);

        // 转换为VO
        return this.convertToVO(document);
    }

    @Override
    public Page<CollabDocumentVO> queryDocumentPage(CollabDocumentQueryRequest request, Long userId) {
        // 构建查询条件
        QueryWrapper<CollabDocumentDO> queryWrapper = this.buildQueryWrapper(request, userId);

        // 分页查询
        Page<CollabDocumentDO> page = new Page<>(request.getPageNum(), request.getPageSize());
        Page<CollabDocumentDO> documentPage = this.page(page, queryWrapper);

        // 转换为VO
        Page<CollabDocumentVO> voPage = new Page<>(request.getPageNum(), request.getPageSize(), documentPage.getTotal());
        List<CollabDocumentVO> voList = documentPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        voPage.setRecords(voList);

        return voPage;
    }

    @Override
    public List<CollabDocumentVersionVO> getDocumentVersions(Long docId, Long userId) {
        // 验证文档存在
        CollabDocumentDO document = this.getById(docId);
        if (document == null || document.getIsDelete() == 1) {
            throw new RuntimeException(ResultCodeEnum.DOCUMENT_NOT_FOUND.getMessage());
        }

        // 检查权�?        this.checkPermission(document, userId, 1);

        // 查询版本列表
        QueryWrapper<CollabDocumentVersion> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("doc_id", docId);
        queryWrapper.eq("is_delete", 0);
        queryWrapper.orderByDesc("version");

        List<CollabDocumentVersion> versions = collabDocumentVersionMapper.selectList(queryWrapper);

        // 转换为VO
        return versions.stream()
                .map(this::convertVersionToVO)
                .collect(Collectors.toList());
    }

    @Override
    public CollabDocumentVersionVO getDocumentVersion(Long docId, Integer version, Long userId) {
        // 验证文档存在
        CollabDocumentDO document = this.getById(docId);
        if (document == null || document.getIsDelete() == 1) {
            throw new RuntimeException(ResultCodeEnum.DOCUMENT_NOT_FOUND.getMessage());
        }

        // 检查权�?        this.checkPermission(document, userId, 1);

        // 查询指定版本
        QueryWrapper<CollabDocumentVersion> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("doc_id", docId);
        queryWrapper.eq("version", version);
        queryWrapper.eq("is_delete", 0);

        CollabDocumentVersion versionEntity = collabDocumentVersionMapper.selectOne(queryWrapper);
        if (versionEntity == null) {
            throw new RuntimeException("指定版本不存在");
        }

        // 转换为VO
        return this.convertVersionToVO(versionEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean lockDocument(Long id, Integer status, Long userId) {
        CollabDocumentDO document = this.getById(id);
        if (document == null || document.getIsDelete() == 1) {
            throw new RuntimeException(ResultCodeEnum.DOCUMENT_NOT_FOUND.getMessage());
        }

        this.checkPermission(document, userId, 2);

        // 如果要锁定，检查是否已被其他用户锁�?
        if (status == 1 && document.getEditStatus() == 1 && !document.getLastEditorUid().equals(userId)) {
            throw new RuntimeException(ResultCodeEnum.DOCUMENT_EDIT_LOCKED.getMessage());
        }

        document.setEditStatus(status);
        return this.updateById(document);
    }

    @Override
    public QueryWrapper<CollabDocumentDO> buildQueryWrapper(CollabDocumentQueryRequest request, Long userId) {
        QueryWrapper<CollabDocumentDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_delete", 0);

        // 文档ID
        if (request.getId() != null) {
            queryWrapper.eq("id", request.getId());
        }

        // 文档类型
        if (request.getDocType() != null) {
            queryWrapper.eq("doc_type", request.getDocType());
        }

        // 队伍ID
        if (request.getTeamId() != null) {
            queryWrapper.eq("team_id", request.getTeamId());
        }

        // 创建者ID
        if (request.getCreatorUid() != null) {
            queryWrapper.eq("creator_uid", request.getCreatorUid());
        }

        // 标题关键�?
        if (StringUtils.isNotBlank(request.getTitleKeyword())) {
            queryWrapper.like("doc_title", request.getTitleKeyword());
        }

        // 默认查询条件：个人文档或队伍文档
        queryWrapper.and(wrapper -> wrapper
                .eq("team_id", 0) // 个人文档
                .or()
                .eq("creator_uid", userId) // 我创建的文档
        );

        // 按更新时间倒序
        queryWrapper.orderByDesc("update_time");

        return queryWrapper;
    }

    @Override
    public void checkPermission(CollabDocumentDO document, Long userId, Integer requiredPermission) {
        // 文档所有者有所有权�?
        if (document.getCreatorUid().equals(userId)) {
            return;
        }

        // 个人文档只能所有者访�?
        if (document.getTeamId() == 0) {
            throw new RuntimeException(ResultCodeEnum.DOCUMENT_PERMISSION_DENIED.getMessage());
        }

        // 检查权限级�?
        if (document.getPermission() < requiredPermission) {
            throw new RuntimeException(ResultCodeEnum.DOCUMENT_PERMISSION_DENIED.getMessage());
        }
    }

    /**
     * 转换实体类为VO
     */
    private CollabDocumentVO convertToVO(CollabDocumentDO document) {
        CollabDocumentVO vo = new CollabDocumentVO();
        BeanUtils.copyProperties(document, vo);
        
        // 设置文档类型中文名称
        switch (document.getDocType()) {
            case 1:
                vo.setDocTypeName("日报");
                break;
            case 2:
                vo.setDocTypeName("周报");
                break;
            case 3:
                vo.setDocTypeName("月报");
                break;
            case 4:
                vo.setDocTypeName("自定义文档");
                break;
            default:
                vo.setDocTypeName("未知类型");
        }
        
        return vo;
    }

    /**
     * 转换版本实体类为VO
     */
    private CollabDocumentVersionVO convertVersionToVO(CollabDocumentVersion version) {
        CollabDocumentVersionVO vo = new CollabDocumentVersionVO();
        BeanUtils.copyProperties(version, vo);
        return vo;
    }
}
